package net.es.oscars.coord.runtimepce;

import org.apache.log4j.Logger;

import net.es.oscars.logging.ErrSev;
import net.es.oscars.logging.ModuleName;
import net.es.oscars.logging.OSCARSNetLogger;
import net.es.oscars.pce.soap.gen.v06.AggregatorCommitContent;
import net.es.oscars.pce.soap.gen.v06.AggregatorCreateContent;
import net.es.oscars.pce.soap.gen.v06.AggregatorModifyContent;
import net.es.oscars.pce.soap.gen.v06.AggregatorCancelContent;
import net.es.oscars.pce.soap.gen.v06.PCECancelContent;
import net.es.oscars.pce.soap.gen.v06.PCECancelReplyContent;
import net.es.oscars.pce.soap.gen.v06.PCECommitContent;
import net.es.oscars.pce.soap.gen.v06.PCECommitReplyContent;
import net.es.oscars.pce.soap.gen.v06.PCECreateContent;
import net.es.oscars.pce.soap.gen.v06.PCEModifyContent;
import net.es.oscars.pce.soap.gen.v06.PCEModifyReplyContent;
import net.es.oscars.pce.soap.gen.v06.PCEReplyContent;
import net.es.oscars.pce.soap.gen.v06.PCEPortType;
import net.es.oscars.pce.soap.gen.v06.PCEDataContent;
import net.es.oscars.pce.soap.gen.v06.TagDataContent;
import net.es.oscars.pce.soap.gen.v06.PCEError;

import net.es.oscars.common.soap.gen.OSCARSFault;
import net.es.oscars.common.soap.gen.OSCARSFaultMessage;
import net.es.oscars.utils.svc.ServiceNames;
import net.es.oscars.utils.sharedConstants.StateEngineValues;


/**
 * PCERuntimSoapHandler handles the pceReply, pceCommitReply. pceCancel and pceModify messages
 * that are sent asynchronously by the PCE once the respective  operation have completed.
 * 
 * This class was generated by Apache CXF 2.2.3
 * Fri Oct 09 10:53:11 PDT 2009
 * Generated source version: 2.2.3
 * 
 */
@javax.jws.WebService(
                      serviceName = ServiceNames.SVC_PCERUNTIME,
                      portName = "PCEPortType",
                      targetNamespace = "http://oscars.es.net/OSCARS/PCE/20090922",
                      endpointInterface = "net.es.oscars.pce.soap.gen.v06.PCEPortType")
 @javax.xml.ws.BindingType(value = "http://www.w3.org/2003/05/soap/bindings/HTTP/")
public class PCERuntimeSoapHandler implements PCEPortType {

    private static final Logger LOG = Logger.getLogger(PCERuntimeSoapHandler.class.getName());

    /**
     *  pceCreate not implemented here. PCERuntime does receive Queries or commits.
     */
    public void pceCreate(PCECreateContent pceCreate)   { 
        String event = "pceCreate";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceCreate.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        LOG.error(netLogger.error(event,ErrSev.MINOR,"Executing operation pceCreate - Should not happen"));
        // The PCE Runtime is not expected to receive any PCE Create. Only replies.
        throw new RuntimeException("PCE Runtime received a PCECreate.");
    }

    /**
     *  aggregatorCreate not implemented here. PCERuntime does receive Queries or commits.
     */
    public void aggregatorCreate(AggregatorCreateContent aggregatorCreate) { 
        String event = "aggregatorCreate";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = aggregatorCreate.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        LOG.error(netLogger.error(event,ErrSev.MINOR,"Executing operation aggregatorCreate - Should not happen"));
        // The PCE Runtime is not expected to receive any queries. Only replies.
        throw new RuntimeException("PCE Runtime received a aggregatorCreate.");
    }

    /**
     *  aggregatorModify not implemented here. PCERuntime does receive Queries or commits.
     */
    public void aggregatorModify(AggregatorModifyContent aggregatorModify )  { 

        String event = "aggregatorModify";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = aggregatorModify.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        LOG.error(netLogger.error(event,ErrSev.MINOR,"Executing operation aggregatorModify - Should not happen"));
        // The PCE Runtime is not expected to receive any queries. Only replies.
        throw new RuntimeException("PCE Runtime received a aggregatorModify.");
    }

    /**
     *  aggregatorCommit not implemented here. PCERuntime does receive Queries or commits.
     */
    public void aggregatorCommit(AggregatorCommitContent aggregatorCommit )  { 

        String event = "aggregatorCommit";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = aggregatorCommit.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        LOG.error(netLogger.error(event,ErrSev.MINOR,"Executing operation aggregatorCommit - Should not happen"));
        // The PCE Runtime is not expected to receive any queries. Only replies.
        throw new RuntimeException("PCE Runtime received a aggregatorCommit.");
    }

    /**
     *  aggregatorCancel not implemented here. PCERuntime does receive Queries or commits.
     */
    
    public void aggregatorCancel(AggregatorCancelContent aggregatorCancel)  { 

        String event = "aggregatorCancel";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = aggregatorCancel.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        LOG.error(netLogger.error(event,ErrSev.MINOR,"Executing operation aggregatorCancel - Should not happen"));
        // The PCE Runtime is not expected to receive any queries. Only replies.
        throw new RuntimeException("PCE Runtime received a aggregatorCancel.");
    }

    /**
     * Handles the pceReply message sent from a PCE or an aggregator when it completes a PCECreate request. 
     * It calls the PCE/AggProxyAction that sent the PCEcreate message to process the replyData.
     * If an error was returned, the proxyAction and the reservation will be set to FAILED. 
     * If no error was returned, the proxyAction will do the next thing on its list.
     */
    public void pceReply(PCEReplyContent pceReply) { 
        String method = "PCERuntimeSoapHandler.pceReply";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceReply.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        netLogger.setGRI(pceReply.getGlobalReservationId());
        String pceName = pceReply.getPceName();
        LOG.debug(netLogger.start(method, " from " + pceName));

        handleReply( method, 
                     netLogger,
                     pceReply.getGlobalReservationId(),
                     pceReply.getPceName(), 
                     pceReply.getPceData(), 
                     pceReply.getPceError());
    }

    public void pceCommit(PCECommitContent pceCommit ) { 
        String event = "pceCommit";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceCommit.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        netLogger.setGRI(pceCommit.getGlobalReservationId());
        LOG.error(netLogger.error(event,ErrSev.MINOR,"Executing operation pceCommit - Should not happen"));
        // The PCE Runtime is not expected to receive any queries. Only replies.
        throw  new RuntimeException("Executing operation pceCommit - Should not happen");
    }

    /**
     * Handles the pceCommitReply message sent from a PCE once it has completed a PCECommit. 
     * If it did not get an error it calls the pce action that sent the commit to 
     * do the next thing on its list. If there was an error it sets the pce action to fail.
     */
    public void pceCommitReply(PCECommitReplyContent pceCommitReply)  { 
        String method = "PCERuntimeSoapHandler.pceCommitReply";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceCommitReply.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        String globalReservationId = pceCommitReply.getGlobalReservationId();
        netLogger.setGRI(globalReservationId);
        String pceName = pceCommitReply.getPceName();
        PCEDataContent pceDataContent = pceCommitReply.getPceData();
        PCEError pceError = pceCommitReply.getPceError();
        LOG.debug(netLogger.start(method, " from " + pceName));
        handleReply( method, netLogger, globalReservationId, pceName, pceDataContent, pceError);
    }
    

    public void pceModify(PCEModifyContent pceModify) { 
        
        String method = "PCERuntimeSoapHandler.pceModify";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceModify.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        String globalReservationId = pceModify.getGlobalReservationId();
        LOG.error(netLogger.error(method, ErrSev.MINOR, "Executing operation pceModify - Should not happen"));
        // The PCE Runtime is not expected to receive any PCE Modify. Only replies.
        throw new RuntimeException("PCE Runtime received a PCEModify.");
    }

    /**
     * Handles the pceModifyReply message sent from a PCE once it has completed a PCEModify. 
     * If it did not get an error it calls the pce action that sent the commit to 
     * do the next thing on its list. If there was an error it sets the pce action to fail.
     */
    public void pceModifyReply(PCEModifyReplyContent pceModifyReply) { 
        String method = "PCERuntimeSoapHandler.pceModifyReply";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceModifyReply.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        String globalReservationId = pceModifyReply.getGlobalReservationId();
        netLogger.setGRI(globalReservationId);
        String pceName = pceModifyReply.getPceName();
        LOG.debug(netLogger.start(method, " from " + pceName));
        PCEDataContent pceDataContent = pceModifyReply.getPceData();
        PCEError pceError = pceModifyReply.getPceError();
        handleReply( method, netLogger, globalReservationId, pceName, pceDataContent, pceError);
    }
    

    public void pceCancel(PCECancelContent pceCancel) { 
        String method = "PCERuntimeSoapHandler.pceCancel";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceCancel.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        String globalReservationId = pceCancel.getGlobalReservationId();
        netLogger.setGRI(globalReservationId);
        LOG.error(netLogger.error(method, ErrSev.MINOR,"Executing operation pceCancel - Should not happen"));
        // The PCE Runtime is not expected to receive any PCE Cancel. Only replies.
        throw new RuntimeException("PCE Runtime received a PCECancel.");
    }

    public void pceCancelReply(PCECancelReplyContent pceCancelReply)  { 

        String method = "PCERuntimeSoapHandler.pceCancelReply";
        OSCARSNetLogger netLogger = OSCARSNetLogger.getTlogger();
        String transId = pceCancelReply.getMessageProperties().getGlobalTransactionId();
        netLogger.init(ModuleName.PCERUNTIME, transId);
        String globalReservationId = pceCancelReply.getGlobalReservationId();
        String pceName = pceCancelReply.getPceName();
        LOG.debug(netLogger.start(method, " from " + pceName));
        netLogger.setGRI(globalReservationId);
        PCEDataContent pceDataContent = pceCancelReply.getPceData();
        PCEError pceError = pceCancelReply.getPceError();
        handleReply(method, netLogger, globalReservationId, pceName, pceDataContent, pceError);
    }
    /* provides boiler plate for handling replies.
     * Calls the pceProxyAction processReply method which will send the resultData
     * to the next agg/pce in the graph
     */
    private void handleReply(String method,
                             OSCARSNetLogger netLogger,
                             String globalReservationId,
                             String pceName,
                             PCEDataContent pceDataContent,
                             PCEError pceError) 
                throws RuntimeException { 

        String requestType = this.getRequestType(method);
        if (requestType == null) {
            LOG.error(netLogger.error(method,ErrSev.MINOR,"Invalid request:null"));
            // This cannot happen, but this is a safety code.
            throw new RuntimeException("Invalid request");
        }
 
        ProxyAction pce = PCERuntimeAction.getProxyAction (globalReservationId, pceName, requestType);

        // Find the PCEProxyAction for which this reply is for.
        if (pce == null) {
            // The destination PCE does not exist. The reply is invalid. Return a fault
            LOG.error(netLogger.error(method,ErrSev.MINOR,"Invalid GRI/name: pce is null"));
            throw new RuntimeException("Invalid GRI/name.");
        }
        try {
            if (pceError != null || pceDataContent == null) {
                OSCARSFault of  = new OSCARSFault();
                of.setMsg(pceError.getMsg());
                of.setDetails(pceError.getDetails());
                OSCARSFaultMessage ofm = new OSCARSFaultMessage("Error in pceReply ", of);
                pce.fail(ofm, StateEngineValues.FAILED);
                LOG.warn(netLogger.error(method,ErrSev.MINOR, "PCEReply sent error message " + 
                         pceError.getMsg() + " with details " +
                         pceError.getDetails()));
                pce.process(); // will notify anyone waiting on this action
                throw ofm;
            } 
            // call the pceProxyAction processReply method which continues the pce graph
            PCEData pceData = new PCEData (pceDataContent.getUserRequestConstraint(),
                                           pceDataContent.getReservedConstraint(),
                                           pceDataContent.getOptionalConstraint(),
                                           pceDataContent.getTopology());
            pce.processReply(pceData);
        } catch (Exception ex) {
            LOG.error(netLogger.error(method, ErrSev.MINOR," caught exception " + ex.getMessage()));
            pce.fail(ex, StateEngineValues.FAILED);
            throw new RuntimeException("PCE runtime pceReply caught exception " +  ex.getMessage());
        }
    }
    
    private String getRequestType (String method) {
        
        if ("PCERuntimeSoapHandler.pceReply".equals(method)) {
            return "pceCreate";
        } else if ("PCERuntimeSoapHandler.pceCommitReply".equals(method)) {
            return "pceCommit";
        } else if ("PCERuntimeSoapHandler.pceModifyReply".equals(method)) {
            return "pceModify";
        } else if ("PCERuntimeSoapHandler.pceCancelReply".equals(method)) {
            return "pceCancel";
        }
        return null;
    }
}
